package de.pharmacontrol.psa.beans;

import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import de.pharmacontrol.pilot.entities.Line;
import de.pharmacontrol.pilot.entities.LogEntry;
import de.pharmacontrol.pilot.entities.LogEntry.Type;
import de.pharmacontrol.pilot.entities.User;
import de.pharmacontrol.psa.LazyList;
import de.pharmacontrol.psa.beans.interfaces.LogEntryService;

@Stateless
public class LogEntryServiceBean implements LogEntryService {

	@PersistenceContext(unitName = "pilot")
	protected EntityManager em;

	@Override
	public LogEntry createLogEntry(String message, Type type, User user, Line line) {
		LogEntry logEntry = new LogEntry();
		logEntry.setType(type);
		logEntry.setMessage(message);
		logEntry.setUser(user);
		logEntry.setLine(line);
		logEntry.setTime(new Timestamp(new Date().getTime()));
		em.persist(logEntry);
		return logEntry;
	}

	@Override
	public List<LogEntry> findAllLogEntries(String messagePattern, User user, Line line) {
		TypedQuery<LogEntry> q;
		final String orderBy = " ORDER BY l.time ASC";
		if (messagePattern == null || messagePattern.isEmpty()) {
			if (user != null && line != null) {
				q = em.createQuery("SELECT l FROM LogEntry l WHERE l.line = :line and l.user = :user"+orderBy, LogEntry.class).setParameter("line", line).setParameter("user", user);
			} else if (line != null) {
				q = em.createQuery("SELECT l FROM LogEntry l WHERE l.line = :line"+orderBy, LogEntry.class).setParameter("line", line);
			} else if (user != null) {
				q = em.createQuery("SELECT l FROM LogEntry l WHERE l.user = :user"+orderBy, LogEntry.class).setParameter("user", user);
			} else {
				q = em.createQuery("SELECT l FROM LogEntry l"+orderBy, LogEntry.class);
			}
		} else {
			if (user != null && line != null) {
				q = em.createQuery("SELECT l FROM LogEntry l WHERE l.line = :line and l.user = :user and l.message like :msg"+orderBy, LogEntry.class).setParameter("line", line).setParameter("user", user).setParameter("msg", "%" + messagePattern + "%");
			} else if (line != null) {
				q = em.createQuery("SELECT l FROM LogEntry l WHERE l.line = :line and l.message like :msg"+orderBy, LogEntry.class).setParameter("line", line).setParameter("msg", "%" + messagePattern + "%");
			} else if (user != null) {
				q = em.createQuery("SELECT l FROM LogEntry l WHERE l.user = :user and l.message like :msg"+orderBy, LogEntry.class).setParameter("user", user).setParameter("msg", "%" + messagePattern + "%");
			} else {
				q = em.createQuery("SELECT l FROM LogEntry l WHERE l.message like :msg"+orderBy, LogEntry.class).setParameter("msg", "%" + messagePattern + "%");
			}
		}
		q.setMaxResults(5000);
		return q.getResultList();
	}

	public Collection<?> getPagedLogEntries(Line line, int pageSize) {
		return new LazyList(em.createQuery("SELECT l FROM LogEntry l WHERE l.line = :line").setParameter("line", line), pageSize, (Long) em.createQuery("SELECT COUNT(l) FROM LogEntry l WHERE line = :line").setParameter("line", line).getSingleResult());
	}

	@Override
	public int getLogEntryCount() {
		TypedQuery<Number> query = em.createQuery("SELECT COUNT(l) FROM LogEntry l", Number.class);
		int size = 0;
		try {
			size = query.getSingleResult().intValue();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return size;

	}

	@Override
	public int getLogEntryCount(String searchPattern) {
		TypedQuery<Number> query = em.createQuery("SELECT COUNT(l) FROM LogEntry l WHERE l.message like :msg", Number.class);
		query.setParameter("msg", "%" + searchPattern + "%");
		int size = 0;
		try {
			size = query.getSingleResult().intValue();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return size;

	}

	@Override
	public List<LogEntry> findPagedLogEntries(int first, int pageSize, String searchPattern, boolean asc) {
		TypedQuery<LogEntry> query;
		try {
			if (searchPattern == null || searchPattern.isEmpty()){
				query = em.createQuery("SELECT l FROM LogEntry l ORDER BY l.time " + (asc ? "ASC" : "DESC"), LogEntry.class);
			}else{
				query = em.createQuery("SELECT l FROM LogEntry l WHERE l.message like :msg ORDER BY l.time " + (asc ? "ASC" : "DESC"), LogEntry.class);
				query.setParameter("msg", "%" + searchPattern + "%");
			}
			query.setFirstResult(first);
			query.setMaxResults(pageSize);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

		return query.getResultList();
	}

}
